Integration Guide Doosan
Note: This integration guide describes the Robot module for an older version of the communication interface (BPS 1.11). The module works with the current Bin Picking Studio (BPS) because of backward compatibility. It does not support features added later (for example, keyed Info data).
Note: We strongly recommend that you read the Robot communication overview before this integration guide.
Contents
1 Prerequisites
The Robot module is compatible with robot controller version GF020500 (2.5.0) and later.
2 Robot controller setup
2.1 Controller configuration
2.1.1 Network configuration
On the teach pendant (TP), open the Setting window from the bottom menu. Then select Network in the list on the left. Configure the static IP address for your network. Make sure that the robot controller and the vision controller are on the same subnet. To confirm the changes, click the Set button.
2.2 Robot module installation
The Robot module consists of three core DRL script files in the scripts folder:
customer_definitions.txt
photoneo_common.txt
state_server.txt
Photoneo also provides three bin picking example programs and one semi-automatic calibration example program. They are also DRL scripts and are in the example_programs-scripts folder:
main_basic.txt
main_multiple_vision_systems.txt
main_change_solution.txt
main_calibration.txt
You can use these scripts to create your own bin picking tasks, as explained later.
The example_programs-tasks folder contains Task Writer *.tw files. Each file combines the core scripts and one example program script into a complete task. You can run the task after you import it into the TP:
BasicExample.tw
MultipleVisionSystemsExample.tw
ChangeSolutionExample.tw
Calibration.tw
CalibrationSemiAuto.tw
Note: The CalibrationSemiAuto.tw task contains the semi-automatic calibration example (the DRL script main_calibration.txt). The Calibration.tw task lets you calibrate by hand guiding. For more details about calibration, see this chapter.
2.2.1 Loading the example program
You can use the TP to import the files into the robot controller directly from a USB stick.
To import an example program (a complete task), select Task Writer (for *.tw files) in the bottom menu. In the list on the left, select Import and then click the Search button. A window opens and shows your USB stick. Select it and find your task file. The task opens. To save the task, press the menu icon in the top left corner (☰) and press Save.
The task combines the core DRL scripts and a bin picking example program, which is also a script. For more information on how to run this task, see this chapter.
2.2.2 Creating a new program from scratch
Each main bin picking program must include the core DRL scripts state_server.txt, photoneo_common.txt, and customer_definitions.txt.
Create a new task in Task Builder or Task Writer (bottom menu). Insert the scripts at the beginning of the MainSub section of the task. To do this, select Command and then select the Custom Code instruction from the list.
Select the new Custom Code instruction and open its Property panel. Then select Import as shown below. A window opens. Select your USB stick and the DRL script file. Press the Confirm button.
Repeat these steps for each core DRL script.
Then you can write your own bin picking application.
3 Robot module
The Robot module is designed for easy integration into existing applications.
3.1 Robotic API
Note: We strongly recommend that you read the Photoneo robotic API before this section.
3.1.1 Connection procedures
Warning: These procedures are contained in the photoneo_common.txt API section and must not be edited!
Connection procedure |
Description / Usage |
|---|---|
Connect to Action Request Server
|
Description
Establishes a new connection to the Action Request Server.
Input parameters:
Usage
Call the procedure only once, at the beginning of the program. You can send requests only after the connection is established.
pho_wait_for_server('')
|
3.1.2 Communication procedures
Note: For a detailed description of these procedures, see Action Requests.
Warning: These procedures are contained in the photoneo_common.txt API section and must not be edited!
Note: In procedures with the optional parameter wait_time, the default value is -1. This means that the timeout for receiving packets is infinite.
Bin picking requests
Request |
Input variables |
Output variables |
|---|---|---|
Initialization request pho_request_init(pho_start_bin_picking_pose,pho_end_bin_picking_pose,vision_system_id,wait_time = -1) |
||
Note: The pose is a posj object or a list of float values that define the joint angles in degrees. |
|
|
Scan request pho_request_scan(vision_system_id) |
|
Note: The Wait for scan completion procedure receives the response. |
Trajectory request pho_request_trajectory(vision_system_id) |
|
Note: The Receive trajectory procedure receives the response. |
Pick-failed request pho_request_send_pick_failed(vision_system_id) |
|
|
Change scene state request pho_request_change_env_state(state_id) |
|
|
Calibration requests
Request |
Input variables |
Output variables |
|---|---|---|
Add calibration point request pho_request_calib_add_point() |
— |
|
Solution requests
Request |
Input variables |
Output variables |
|---|---|---|
Change solution request pho_request_change_solution(required_solution_id) |
|
|
Start solution request pho_request_start_solution(required_solution_id) |
|
|
Stop solution request pho_request_stop_solution() |
— |
|
Get running solution request pho_request_get_running_solution() |
— |
|
Get available solutions request pho_request_get_available_solutions() |
— |
|
Response receiving procedures
Response receiving procedures |
Input variables |
Output variables |
|---|---|---|
Wait for scan completion pho_wait_for_scan_completion(wait_time = -1) |
|
|
Receive trajectory pho_receive_trajectory(wait_time = -1) |
|
|
3.1.3 Bin picking procedures
Note: These procedures are in the customer_definitions.txt API section. Implement (edit) them as your application requires.
Bin picking procedure |
Description / Usage |
|---|---|
Gripper attach gripper_attach() |
Description
A user-defined procedure. Typically, it is the attach procedure for grasping the picked object in the Grasp waypoint.
Usage
It runs automatically when the robot reaches a grasping method waypoint that is configured to run the Attach procedure.
|
Gripper detach gripper_detach() |
Description
A user-defined procedure. Typically, it is the detach procedure for releasing the picked object in the placing routine that the robot operator defines.
Usage
It runs automatically when the robot reaches a grasping method waypoint that is configured to run the Detach procedure.
Note: Typically, this procedure is not configured to run automatically in a waypoint. It is called during placing, which the robot operator implements. |
Gripper user-defined 1 gripper_user_1() |
Description
A user-defined procedure.
Usage
It runs automatically when the robot reaches a grasping method waypoint that is configured to run the User 1 procedure.
|
Gripper user-defined 2 gripper_user_2() |
Description
A user-defined procedure.
Usage
It runs automatically when the robot reaches a grasping method waypoint that is configured to run the User 2 procedure.
|
Gripper user-defined 3 gripper_user_3() |
Description
A user-defined procedure.
Usage
It runs automatically when the robot reaches a grasping method waypoint that is configured to run the User 3 procedure.
|
Execute bin picking routine pho_bin_picking() |
Description
Predefined procedure that runs the bin picking routine. You must not edit this procedure directly. To adapt the execution settings, see Bin picking routine execution settings.
Usage
Run it after the bin picking trajectory is received. The robot must be in the start pose when the procedure starts. At the end of the procedure, the robot is in the end pose with the picked object attached to the gripper.
Warning: If you use multiple start poses (different for each vision system), make sure that the robot is in the correct one before you run this procedure. |
Set bin picking settings binpicking_settings() |
Description
Predefined procedure that configures the parameters of the individual trajectory segments of the bin picking routine.
Usage
It is called automatically before the bin picking routine runs.
Note: For more about bin picking routine configuration, see Bin picking routine execution settings. |
3.2 Example programs
This section contains basic example programs. Each program is for a specific bin picking application and shows the correct use of the robotic API.
These templates also contain simple error handling. It is only an example. You must define your own routines for error situations.
3.2.1 Basic bin picking example
This program is a very basic example of a simple bin picking application. It connects to the vision controller and initializes one vision system. Then, in a loop, it requests a scan and a trajectory, and executes the received trajectory.
Name: main_basic.txt (DRL script in the example_programs-scripts folder, used in the BasicExample.tw task in the example_programs-tasks folder)
# BasicExample module v.1.7
# Copyright(c) 2023 Photoneo s.r.o.
# All rights reserved
# Adjust Vision Controller IP address if necessary
BINPICKING_SRV_IP = ''
# Definition of global variables (proper values are set in the main function)
home_pose = None
start_pose = None
end_pose = None
MAX_ERR_COUNT = 2
err_counter = 0
def main_binpicking_example_basic():
global pho_err_code, pho_err_occurred, err_counter, BINPICKING_SRV_IP, home_pose, start_pose, end_pose
# Start the state server in a separate thread
pho_start_state_server()
# Reset state of error handling variables
err_counter = 0
pho_err_code = PhoCommErr.OK
# Note that: Instead of the poses definitions below you may also
# use joint pose variables defined in the task (in properties of task commands: GlobalVariables / Define),
# where you can adjust the values more easily when working with teach pendant
# Reteach home position for your application
home_pose = posj(167.0, -27.0, -101.0, 178.0, 48.0, -16.0)
# Reteach bin picking start and end pose
start_pose = posj(167.0, -38.0, -101.0, 178.0, 48.0, -16.0)
end_pose = posj(150.0, -38.0, -101.0, 178.0, 48.0, -16.0)
# Set Vision System ID (default = 1)
vision_system_id = 1
# Connect to the Vision Controller,
if not pho_wait_for_server(BINPICKING_SRV_IP):
exit()
# Send bin picking initialization request for the current Vision System ID,
# start & end poses sent via this request will be used in trajectory planning pipeline
pho_request_init(start_pose, end_pose, vision_system_id)
# Move the robot out of the scanning volume!
movej(home_pose, v=50, a=150)
# Request first scan
pho_request_scan(vision_system_id)
while True:
# ==================== PHOTONEO BIN PICKING START ====================
# Wait for scan completion
pho_wait_for_scan_completion()
# Handle errors if occurred
if pho_err_occurred:
err_handling(vision_system_id)
continue # start the loop again
# Request trajectory
pho_request_trajectory(vision_system_id)
# Move to start position while the trajectory is being calculated
movej(start_pose, v=50, a=200)
# Receive trajectory (sequence of operations & operations data)
pho_receive_trajectory()
# Execute bin picking application if the trajectory was received with no error
if not pho_err_occurred:
pho_bin_picking()
# ==================== PHOTONEO BIN PICKING END ====================
if pho_err_occurred:
err_handling(vision_system_id)
continue
else:
# Clear error counter
err_counter = 0
# ==================== PLACING START ====================
# Move the robot away so that we can trigger a new scan
# movej(home_pose, v=50, a=150)
# Trigger next scan, so that
# localization and trajectory computation for the next cycle can run while the object is being placed
pho_request_scan(vision_system_id)
# Commands for actual part placing (reteach position for your robot and work cell)
# movej(posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0), v=50, a=100)
# gripper_detach()
# movej(home_pose, v=50, a=150)
# ==================== PLACING END ====================
def err_handling(vision_system_id):
global pho_err_occurred, pho_err_code, MAX_ERR_COUNT, err_counter, \
home_pose, start_pose, end_pose, BINPICKING_SRV_IP
# Release the gripper if necessary
# gripper_detach()
# Move robot to home pose
movej(home_pose, v=50, a=150)
# Log the error
err_code_str = '"{}" ({})'.format(
PhoCommErrND.get(pho_err_code, PhoBipiErrND.get(pho_err_code, '?')),
pho_err_code)
tp_log('Error occurred: {}'.format(err_code_str))
if err_counter >= MAX_ERR_COUNT:
# Log error & exit (exits via the popup window)
tp_popup('Photoneo internal error: {}. '
'Please reboot the Vision Controller and restart application'.format(err_code_str),
DR_PM_ALARM, 1)
# If planning failed or no part was found, notify user and continue by a new scan request (Adjust if necessary)
if pho_err_code in [PhoBipiErr.PLANNING_FAILED, PhoBipiErr.NO_PART_FOUND]:
tp_log('No part found or path planning failed')
pho_request_scan(vision_system_id)
# If bin picking has not been initialized or service returned error response,
# reinitialize and send a new scan request (Adjust if necessary)
elif pho_err_code == PhoBipiErr.NOT_INITIALIZED:
wait(5.0)
pho_request_init(start_pose, end_pose, vision_system_id)
pho_request_scan(vision_system_id)
# if bin picking returned error response, reinitialize and trigger a new scan (Adjust if necessary)
elif pho_err_code == PhoCommErr.SERVICE_ERR:
wait(10.0)
pho_request_init(start_pose, end_pose, vision_system_id)
pho_request_scan(vision_system_id)
# In case of communication failure, log the error and exit program
elif pho_err_code in [PhoCommErr.BAD_DATA, PhoCommErr.TIMEOUT, PhoCommErr.COMM_FAILURE]:
wait(10.0)
pho_wait_for_server(BINPICKING_SRV_IP)
pho_request_init(start_pose, end_pose, vision_system_id)
pho_request_scan(vision_system_id)
# Otherwise trigger next scan and try to continue
else:
pho_request_scan(vision_system_id)
err_counter += 1
# Clear the error flag
pho_err_occurred = False
main_binpicking_example_basic()
3.2.2 Multiple Vision Systems example
This program extends the basic bin picking example. It initializes two vision systems instead of one and switches between them in each cycle.
Name: main_multiple_vision_systems.txt (DRL script in the example_programs-scripts folder, used in the MultipleVisionSystemsExample.tw task in the example_programs-tasks folder)
# MultipleVisionSystemExample module v.1.7
# Copyright(c) 2023 Photoneo s.r.o.
# All rights reserved
# Adjust Vision Controller IP address if necessary
BINPICKING_SRV_IP = ''
# Definition of global variables (proper values are set in the main function)
home_pose = None
start_pose = None
end_pose = None
MAX_ERR_COUNT = 5
err_counter = 0
def main_multiple_vision_systems_example():
global pho_err_code, pho_err_occurred, err_counter, BINPICKING_SRV_IP, home_pose, start_pose, end_pose
# Start the state server in a separate thread
pho_start_state_server()
# Reset state of error handling variables
err_counter = 0
pho_err_code = PhoCommErr.OK
# Set Vision System ID (default = 1)
vision_system_ids = [1, 2]
active_vision_system_id = vision_system_ids[0]
# Note that: Instead of the poses definitions below you may also
# use joint pose variables defined in the task (in properties of task commands: GlobalVariables / Define),
# where you can adjust the values more easily when working with teach pendant
# An example code of using GlobalVariables from a task is commented below
# or you may use the provided task MultipleVisionSyxtemsExample.tw which has poses defined in GlobalVariables
# Reteach home pose, bin picking start and end pose for your application
# home_pose = Global_home_pose
# start_pose = {vision_system_ids[0]: Global_start_pose_1,
# vision_system_ids[1]: Global_start_pose_2}
# end_pose = {vision_system_ids[0]: Global_end_pose_1,
# vision_system_ids[1]: Global_end_pose_2}
# Reteach home pose, bin picking start and end pose for your application
# In case you're using poses defined in the task from above, remove/comment pose definitions below
start_pose = {vision_system_ids[0]: posj(3.29, -34.42, 130.6, -6.62, 58.61, -68.77),
vision_system_ids[1]: posj(12.21, -34.42, 130.6, -6.62, 58.61, -68.77)}
end_pose = {vision_system_ids[0]: posj(43.59, 30.48, 92.73, -2.61, 53.47, -73.04),
vision_system_ids[1]: posj(43.59, 30.48, 92.73, -2.61, 53.47, -73.04)}
home_pose = posj(8.29, -34.42, 130.6, -6.62, 58.61, -68.77)
# Connect to the Vision Controller,
if not pho_wait_for_server(BINPICKING_SRV_IP):
exit()
# Send bin picking initialization request for the current Vision System ID,
# start & end poses sent via this request will be used in trajectory planning pipeline
pho_request_init(start_pose[vision_system_ids[0]], end_pose[vision_system_ids[0]], vision_system_ids[0])
pho_request_init(start_pose[vision_system_ids[1]], end_pose[vision_system_ids[1]], vision_system_ids[1])
# Move the robot out of the scanning volume!
movej(home_pose, v=50, a=150)
# Request first scan
pho_request_scan(active_vision_system_id)
while True:
# ==================== PHOTONEO BIN PICKING START ====================
# Wait for scan completion
pho_wait_for_scan_completion()
# Handle errors if occurred
if pho_err_occurred:
err_handling(active_vision_system_id)
continue # start the loop again
# Request trajectory
pho_request_trajectory(active_vision_system_id)
# Move to start position while the trajectory is being calculated
movej(start_pose[active_vision_system_id], v=50, a=200)
# Receive trajectory (sequence of operations & operations data)
pho_receive_trajectory()
# Execute bin picking application if the trajectory was received with no error
if not pho_err_occurred:
pho_bin_picking()
# ==================== PHOTONEO BIN PICKING END ====================
if pho_err_occurred:
err_handling(active_vision_system_id)
continue
else:
# Clear error counter
err_counter = 0
# ==================== PLACING START ====================
# Move the robot away so that we can trigger a new scan
# movej(home_pose, v=50, a=150)
# Switch active vision system
if active_vision_system_id == vision_system_ids[0]:
active_vision_system_id = vision_system_ids[1]
else:
active_vision_system_id = vision_system_ids[0]
# Trigger next scan, so that
# localization and trajectory computation for the next cycle can run while the object is being placed
pho_request_scan(active_vision_system_id)
# Commands for actual part placing (reteach position for your robot and work cell)
# movej(posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0), v=50, a=100)
# gripper_detach()
# movej(home_pose, v=50, a=150)
# ==================== PLACING END ====================
def err_handling(vision_system_id):
global pho_err_occurred, pho_err_code, MAX_ERR_COUNT, err_counter, \
home_pose, start_pose, end_pose, BINPICKING_SRV_IP
# Release the gripper if necessary
# gripper_detach()
# Move robot to home pose
movej(home_pose, v=50, a=150)
# Log the error
err_code_str = '"{}" ({})'.format(
PhoCommErrND.get(pho_err_code, PhoBipiErrND.get(pho_err_code, '?')),
pho_err_code)
tp_log('Error occurred: {}'.format(err_code_str))
if err_counter >= MAX_ERR_COUNT:
# Log error & exit (exits via the popup window)
tp_popup('Photoneo internal error: {}. '
'Please reboot the Vision Controller and restart application'.format(err_code_str),
DR_PM_ALARM, 1)
# If planning failed or no part was found, notify user and continue by a new scan request (Adjust if necessary)
if pho_err_code in [PhoBipiErr.PLANNING_FAILED, PhoBipiErr.NO_PART_FOUND]:
tp_log('No part found or path planning failed')
pho_request_scan(vision_system_id)
# If bin picking has not been initialized or service returned error response,
# reinitialize and send a new scan request (Adjust if necessary)
elif pho_err_code == PhoBipiErr.NOT_INITIALIZED:
wait(5.0)
pho_request_init(start_pose[vision_system_id], end_pose[vision_system_id], vision_system_id)
pho_request_scan(vision_system_id)
# if bin picking returned error response, reinitialize and trigger a new scan (Adjust if necessary)
elif pho_err_code == PhoCommErr.SERVICE_ERR:
wait(10.0)
pho_request_init(start_pose[vision_system_id], end_pose[vision_system_id], vision_system_id)
pho_request_scan(vision_system_id)
# In case of communication failure, log the error and exit program
elif pho_err_code in [PhoCommErr.BAD_DATA, PhoCommErr.TIMEOUT, PhoCommErr.COMM_FAILURE]:
wait(10.0)
pho_wait_for_server(BINPICKING_SRV_IP)
pho_request_init(start_pose[vision_system_id], end_pose[vision_system_id], vision_system_id)
pho_request_scan(vision_system_id)
# Otherwise trigger next scan and try to continue
else:
pho_request_scan(vision_system_id)
err_counter += 1
# Clear the error flag
pho_err_occurred = False
main_multiple_vision_systems_example()
3.2.3 Change solution example
One robotic cell can take part in several production processes. To handle multiple parts at the same time, use multiple vision systems in one solution. If you change the production process completely, it is better to have separate solutions. The robot can deploy them directly.
This program extends the basic bin picking example. After a defined number of bin picking cycles, it sends a request to change the deployed solution.
Name: main_change_solution.txt (DRL script in the example_programs-scripts folder, used in the ChangeSolutionExample.tw task in the example_programs-tasks folder)
# SolutionExample module v.1.7
# Copyright(c) 2023 Photoneo s.r.o.
# All rights reserved
# Adjust Vision Controller IP address if necessary
BINPICKING_SRV_IP = ''
# Definition of global variables (proper values are set in the main function)
home_pose = None
start_pose = None
end_pose = None
MAX_ERR_COUNT = 2
err_counter = 0
CHANGE_SOLUTION_AFTER_PICK_COUNT = 5Name: main_change_solution.txt (DRL script located in folder example_programs-scripts, used in task ChangeSolutionExample.tw located in folder example_programs-tasks)
EXIT_AFTER_SOLUTION_CHANGE = True
def main_solution_example():
global pho_err_code, pho_err_occurred, err_counter, BINPICKING_SRV_IP, home_pose, start_pose, end_pose, \
pho_available_solutions, pho_running_solution
# Start the state server in a separate thread
pho_start_state_server()
# Reset state of error handling variables
err_counter = 0
pho_err_code = PhoCommErr.OK
pick_counter = 0
solution_id_1 = 1
solution_id_2 = 2
actual_solution = solution_id_2
# Note that: Instead of the poses definitions below you may also
# use joint pose variables defined in the task (in properties of task commands: GlobalVariables / Define),
# where you can adjust the values more easily when working with teach pendant
# Reteach home position for your application
home_pose = posj(167.0, -27.0, -101.0, 178.0, 48.0, -16.0)
# Reteach bin picking start and end pose
start_pose = posj(167.0, -38.0, -101.0, 178.0, 48.0, -16.0)
end_pose = posj(150.0, -38.0, -101.0, 178.0, 48.0, -16.0)
# Set Vision System ID (default = 1)
vision_system_id = 1
# Connect to the Vision Controller,
if not pho_wait_for_server(BINPICKING_SRV_IP):
exit()
# Get available solutions
pho_request_get_available_solutions()
tp_log('Available solution/solutions is/are: {}'.format(pho_available_solutions))
# Start solution 1
pho_request_start_solution(solution_id_2)
# Get running solution
pho_request_get_running_solution()
tp_log('Currently is running solution with ID: {}'.format(pho_running_solution))
# Send bin picking initialization request for the current Vision System ID,
# start & end poses sent via this request will be used in trajectory planning pipeline
pho_request_init(start_pose, end_pose, vision_system_id)
# Move the robot out of the scanning volume!
movej(home_pose, v=50, a=150)
# Request first scan
pho_request_scan(vision_system_id)
while True:
# ==================== PHOTONEO BIN PICKING START ====================
# Wait for scan completion
pho_wait_for_scan_completion(5.0)
# Handle errors if occurred
if pho_err_occurred:
err_handling(vision_system_id, actual_solution)
continue # start the loop again
# Request trajectory
pho_request_trajectory(vision_system_id)
# Move to start position while the trajectory is being calculated
movej(start_pose, v=50, a=200)
# Receive trajectory (sequence of operations & operations data)
pho_receive_trajectory()
# Execute bin picking application if the trajectory was received with no error
if not pho_err_occurred:
pho_bin_picking()
# ==================== PHOTONEO BIN PICKING END ====================
if pho_err_occurred:
err_handling(vision_system_id, actual_solution)
continue
else:
# Clear error counter
err_counter = 0
# Increment pick counter
pick_counter += 1
# ==================== PLACING START ====================
# Move the robot away so that we can trigger a new scan
# movej(home_pose, v=50, a=150)
# Do not request scan in case the solution switch will follow after placing the part
if pick_counter < CHANGE_SOLUTION_AFTER_PICK_COUNT:
# Trigger next scan, so that
# localization and trajectory computation for the next cycle can run while the object is being placed
pho_request_scan(vision_system_id)
# Commands for actual part placing (reteach position for your robot and work cell)
# movej(posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0), v=50, a=100)
# gripper_detach()
# movej(home_pose, v=50, a=150)
# ==================== PLACING END ====================
# If required number of picked parts is reached, call change solution request and production will be changed
if pick_counter >= CHANGE_SOLUTION_AFTER_PICK_COUNT:
pick_counter = 0
if actual_solution == solution_id_1:
actual_solution = solution_id_2
else:
actual_solution = solution_id_1
# ==================== CHANGING OF PRODUCTION START ====================
# Move the robot to home position
movej(home_pose, v=50, a=150)
pho_request_change_solution(actual_solution)
# Get running solution
pho_request_get_running_solution()
tp_log('Currently is running solution with ID: {}'.format(pho_running_solution))
pho_wait_for_server(BINPICKING_SRV_IP)
pho_request_init(start_pose, end_pose, vision_system_id)
# Wait 10 sec to see that solution was changed
wait(15.0)
if EXIT_AFTER_SOLUTION_CHANGE:
pho_request_stop_solution()
exit()
else:
pho_request_scan(vision_system_id)
# ==================== CHANGING OF PRODUCTION END ====================
def err_handling(vision_system_id, solution_id):
global pho_err_occurred, pho_err_code, MAX_ERR_COUNT, err_counter, \
home_pose, start_pose, end_pose, BINPICKING_SRV_IP
# Release the gripper if necessary
# gripper_detach()
# Move robot to home pose
movej(home_pose, v=50, a=150)
# Log the error
err_code_str = '"{}" ({})'.format(
PhoCommErrND.get(pho_err_code, PhoBipiErrND.get(pho_err_code, '?')),
pho_err_code)
tp_log('Error occurred: {} (solution ID: {}; Vision System ID: {})'.format(
err_code_str, solution_id, vision_system_id))
if err_counter >= MAX_ERR_COUNT:
# Log error & exit (exits via the popup window)
tp_popup('Photoneo internal error: {}. '
'Please reboot the Vision Controller and restart application'.format(err_code_str),
DR_PM_ALARM, 1)
# If planning failed or no part was found, notify user and continue by a new scan request (Adjust if necessary)
if pho_err_code in [PhoBipiErr.PLANNING_FAILED, PhoBipiErr.NO_PART_FOUND]:
tp_log('No part found or path planning failed')
pho_request_scan(vision_system_id)
# If bin picking has not been initialized or service returned error response,
# reinitialize and send a new scan request (Adjust if necessary)
elif pho_err_code == PhoBipiErr.NOT_INITIALIZED:
wait(5.0)
pho_request_init(start_pose, end_pose, vision_system_id)
pho_request_scan(vision_system_id)
# if bin picking returned error response, reinitialize and trigger a new scan (Adjust if necessary)
elif pho_err_code == PhoCommErr.SERVICE_ERR:
wait(10.0)
pho_request_init(start_pose, end_pose, vision_system_id)
pho_request_scan(vision_system_id)
# In case of communication failure, log the error and exit program
elif pho_err_code in [PhoCommErr.BAD_DATA, PhoCommErr.TIMEOUT, PhoCommErr.COMM_FAILURE]:
wait(10.0)
pho_wait_for_server(BINPICKING_SRV_IP)
pho_request_init(start_pose, end_pose, vision_system_id)
pho_request_scan(vision_system_id)
# Otherwise trigger next scan and try to continue
else:
pho_request_scan(vision_system_id)
err_counter += 1
# Clear the error flag
pho_err_occurred = False
main_solution_example()
3.2.4 Calibration example
This program is a template for semi-automatic calibration.
Before you run the program:
Teach the calibration home pose. The robot moves through this pose to each calibration pose.
Teach the calibration poses.
Start the calibration in BPS.
Now you can start the program. The robot moves to each calibration pose and sends the Add calibration point request when it reaches the pose. Between the calibration poses, the robot moves through the calibration home pose. When all calibration points are added, the program ends. If you are satisfied with the calibration result, save it in BPS.
Name: main_calibration.txt (DRL script in the example_programs-scripts folder, used in the CalibrationSemiAuto.tw task in the example_programs-tasks folder)
# CalibrationExample module v.1.7
# Copyright(c) 2023 Photoneo s.r.o.
# All rights reserved
# Adjust Vision Controller IP address if necessary
BINPICKING_SRV_IP = ''
# Definition of global variables (proper values are set in the main function)
home_pose = None
MAX_ERR_COUNT = 2
err_counter = 0
# calibration_positions should be uncommented and adjusted according to the scene
# calibration_positions = [
# posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
# posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
# posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
# posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
# posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
# posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
# posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
# posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
# posj(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
# ]
def main_calibration_example():
global pho_err_code, pho_err_occurred, err_counter, BINPICKING_SRV_IP, home_pose
# Start the state server in a separate thread
pho_start_state_server()
# Reset state of error handling variables
err_counter = 0
pho_err_code = PhoCommErr.OK
# Note that: Instead of the poses definitions below you may also
# use joint pose variables defined in the task (in properties of task commands: GlobalVariables / Define),
# where you can adjust the values more easily when working with teach pendant
# Reteach home position for your application
home_pose = posj(167.0, -27.0, -101.0, 178.0, 48.0, -16.0)
# Connect to the Vision Controller,
if not pho_wait_for_server(BINPICKING_SRV_IP):
exit()
# Move the robot out of the scanning volume!
movej(home_pose, v=50, a=150)
for calibration_pose in calibration_positions:
# Move robot to one of the calibration position
movej(calibration_pose, v=50, a=150)
# Request for add calibration point
pho_request_calib_add_point()
movej(home_pose, v=50, a=150)
# Check if the error occurred. If there is error the error code is logged to robot logs and the calibration is stopped
if pho_err_occurred:
tp_log('An error has occurred when calibration point was added. The error code is: {} '.format(pho_err_code))
break
main_calibration_example()
3.3 Error handling
If an error occurs while the requested operation runs, the global error flag (pho_error_occurred) is set to true. The error code is stored in the global variable pho_err_code. We recommend that you add suitable error handling for your application after each synchronous request and response receiving procedure.
For the list of error codes with descriptions and troubleshooting, see here.
The most important error codes are defined as constants in the DRL script photoneo_common.txt. They are split into two classes with static variables:
class PhoCommErr
Error code |
DRL constant |
|---|---|
No error (0) |
OK = 0 |
Service error (1) |
SERVICE_ERR = 1 |
Communication error (3) |
COMM_FAILURE = 3 |
Bad data (4) |
BAD_DATA = 4 |
Timeout (5) |
TIMEOUT = 5 |
Error code |
DRL constant |
|---|---|
Path planning failed (201) |
PLANNING_FAILED = 201 |
No object found (202) |
NO_PART_FOUND = 202 |
Vision system not initialized (203) |
NOT_INITIALIZED = 203 |
Empty scene (218) |
EMPTY_SCENE = 218 |
Wrong bin picking configuration (255) |
WRONG_BP_CONF = 255 |
4 Running the basic bin picking example program
4.1 Prerequisites
Before you can run the Basic bin picking example, make sure that:
A fully configured BPS solution with a single vision system is ready for deployment.
The robot controller is configured as described in Robot controller setup.
The BPS network settings are configured.
The gripper procedures are implemented (optional - without them, the robot does not actually pick the object).
The placing procedure is implemented.
4.2 Bin picking routine execution settings
By default, the speeds and accelerations of the first 6 trajectories of the bin picking routine are configured. (The default number of trajectories in a bin picking routine is 4, as defined in the grasping method of the BPS solution.)
For each trajectory, you can define one float value [degrees per second] as the speed for all joints. Or you can define a list of 6 float values as the speeds for the individual joints. The same applies to the acceleration data [degrees per second^2].
Adapt these values to your requirements. If you add custom path stages (trajectories), configure the matching number of values in the pho_speed_data and pho_acceleration_data arrays. Keep the order of the trajectories: the first value (list of 6 values) in the array applies to the first trajectory, the second value (list of 6 values) to the second trajectory, and so on.
max_velocity = [120.0, 120.0, 180.0, 225.0, 225.0, 225.0]
The list of acceleration values per joint is defined as follows (the same value for all 6 joints):
acceleration = [400] * 6
The speeds and accelerations for a trajectory segment are then added to the arrays pho_speed_data and pho_acceleration_data:
pho_speed_data.append([maxvj * 1.0 for maxvj in max_velocity])
pho_acceleration_data.append(acceleration)
4.3 Reteach the robot poses
An important step of the bin picking configuration is to teach the home, start, and end poses. Teach the home position so that the robot is outside the scanning area. Teach the start position so that the robot gripper is approximately above the center of the bin. The end position can be similar to the start position or slightly shifted towards the placing area. Do not define the end pose too far from the bin. This can affect path planning (longer total planning time, planning errors, and so on).
The basic bin picking example program uses the following poses:
home_pose - Home position, a posj object, for example:
home_pose = posj(167.0, -27.0, -101.0, 178.0, 48.0, -16.0)
start_pose - Start position, a posj object or a list of float values defining the joint angles in degrees
end_pose - End position, a posj object or a list of float values defining the joint angles in degrees
You can also define the poses as joint pose variables in the task (in the properties of the task commands: GlobalVariables / Define). This makes it easier to adjust the values on the teach pendant. For example:
home_pose = Global_home_pose
4.4 Runtime
Deploy your BPS solution. On the Deployment page in BPS, the Action Request Client status should be DISCONNECTED (from the Action Request Server).
Before you run a task, start the servo. To do this, open the Status screen and press On. Then close the screen with ‘X’ in the top left corner, as shown below.
When the servo is on, select the task that you want to run. If the correct task is already open (the task name is shown in the top left corner), press the Run button (option A in the image below).
To select a different task, press the Menu button (☰), select Open, and select the task (option B in the images below).
On the Deployment page, the Action Request Client status and the Robot State Server status change to CONNECTED.
The robot now starts to send requests to the vision controller and to execute bin picking movements.
Note: Be ready to stop the robot motion immediately. We strongly recommend that you reduce the speed to 10% of maximum during the first bin picking tests.
4.5 Logging
The Photoneo robotic API uses the function tp_log(). These logs have the default category Log Message, which is not shown while the task runs. Only the most important messages are shown, in a popup window. These are usually fatal errors that stop the task. To see all logged messages from the task, open Settings > Log Message on the TP.
5 Migration guide
This chapter describes how to update your Robot module to a newer version.
5.1 Robot module update
Follow these steps to update your current Robot module to a newer version that is compatible with your BPS version:
Back up your changes in the script customer_definitions.txt. It contains your custom settings and the gripper action procedures.
Remove the scripts that you loaded into your main task: photoneo_common.txt, customer_definitions.txt, and state_server.txt.
Load the new version of these scripts into your main task.
Apply your changes from the old customer_definitions.txt to the new one.
Read the API changes in the new version of the Robot module carefully. If necessary, update the API calls in your main program.
6 Calibration
During calibration, the Robot State Server must run to provide the current state of the robot. The Robot State Server also provides data for hand-eye bin picking and for real-time visualization of the robot. The main Robot State Server functions are in the DRL script state_server.txt. It also needs definitions from photoneo_common.txt. The procedure pho_start_state_server() starts the Robot State Server. It creates a server socket and runs in a separate thread. When a client connects, the server starts to send the robot state data. If the client disconnects, the server waits for a new client.
Because of this, each task must include the script state_server.txt (and photoneo_common.txt) and start the server with this call:
pho_start_state_server()
6.1 Hand guiding
The task Calibration.tw contains the scripts needed to run the Robot State Server. It calls the procedure that starts the server and then starts hand guiding. Before you start the calibration task, make sure that a collaborative zone is enabled. The zone must be large enough for you to jog the robot through all the space needed for calibration. The task does not and cannot check whether the collaborative zone is enabled! If the zone is not enabled, a green light is shown on link 6 and you cannot move the robot. If the collaborative zone is set and the current robot pose is inside the zone, a blue light is shown. This means that you can jog the robot manually while you hold the hand-guide button on the robot cockpit or on the TP. An example of a collaborative zone setting is shown below.
6.2 Semi-automatic
The operator only needs to start the calibration in BPS and finish it (check the result and save it).